/** 
 * 文件名：NginxLogUtil.java 
 * 
 * 版本信息： 
 * 日期：2015年8月29日 
 * Copyright 足下 Corporation 2015 
 * 版权所有 
 * 
 */

package com.qyer.util.log.util;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.mortbay.util.StringUtil;

import com.qyer.util.log.common.Constants;
import com.qyer.util.log.entity.PcBaseLog;
import com.qyer.util.log.entity.NginxLog;

/**
 * 此类描述的是： 原始日志工具类
 * 
 * @author: hongxi.sun@qyer.com
 * @version:  2015年8月29日 下午3:23:38
 */
public class PcLogUtil {
     final static Pattern p1=Pattern.compile("/(mguide|trip|m.qyer.com/place/poi|place.qyer.com/poi|cost|calendar|message|tag|map)/([^/#\\?]+)");
     final static Pattern p2=Pattern.compile("(mguide|trip|m.qyer.com/place/poi|place.qyer.com/poi|cost|calendar|message|tag|map)/(\\d+)");
     
     final static Pattern p3=Pattern.compile("m.qyer.com/plan/([^/#\\?]+)/\\D+/\\d+");
     final static Pattern p4=Pattern.compile("m.qyer.com/plan/\\d+/\\D+/\\d+");
	
     final static Pattern p5=Pattern.compile("guide/((\\d)+/)*page/([^/\\?]+)");
     /**
	 * 判断参数是否为null或者-,是则返回空字符串,否则不做任何处理返回原参数
	 * @param str 需要判断的参数
	 * @author: hongxi.sun@qyer.com
	 * @version:  2015年8月29日 下午3:23:38
	 * @return 
	 */
	public static String formatField(String str){
		if( str==null ||"".equals(str.trim())|| "-" .equals(str)){
			return "";
		}			
		return str;
	}

	/**
	 * 此方法描述的是：解析nginx日志格式成NginxLog对象
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return 返回NginxLog对象,出现异常返回null
	 */
	public static NginxLog getNginxLog(String strLine) {
		if (strLine == null || strLine.equals("")) {
			return null;
		}
		
		
		String   remote_addr="";   
		String   remote_user="";  
		String   time_local	="";  
		String   request="";  
		String   status=""; 
		String   body_bytes_sent="";
		String   http_referer="";
		String   http_user_agent="";
		String   http_x_forwarded_fo="";
	
		if(strLine.contains("\001")){
			String [] ls = StringUtils.split(strLine , Constants.FS);
			if(ls.length<9){
				return null ; 
			}
			
			remote_addr=ls[0];
			remote_user=ls[1];
			time_local=ls[2];
			request=ls[3];
			status=ls[4];
			body_bytes_sent=ls[5];
			http_referer=ls[6];
			http_user_agent=ls[7];
			http_x_forwarded_fo=ls[8];
		}else{
			
			//String [] ls = strLine.split("\""); 
			String [] ls = StringUtils.split(strLine , "\"");
			if( ls.length >= 1){
				String [] arr1 = ls[0].split(" "); 
				if(arr1.length>=5){
					remote_addr=arr1[0];
					remote_user=arr1[2];
					time_local=arr1[3]+" "+arr1[4];
				}
			}
			
			if(ls .length >=2){
				request=ls[1];
			}
			
			if(ls .length >=3){
				String [] arr1 = ls[2].trim().split(" "); 
				if(arr1.length>=2){
					status=arr1[0];
					body_bytes_sent=arr1[1];
				}
			}
				
			if(ls .length >=4){
				http_referer=ls[3];
			}
			
			if(ls .length >=6){
				http_user_agent=ls[5];
			}
			
			if(ls .length >=8){
				http_x_forwarded_fo=ls[7];
			}
		}
		
		
		NginxLog nginxLog = new NginxLog();
		nginxLog.setRemote_addr(formatField(remote_addr));
		nginxLog.setRemote_user(formatField(remote_user));
		nginxLog.setTime_local(formatField(time_local));
		nginxLog.setRequest(formatField(request));
		nginxLog.setStatus(formatField(status));
		nginxLog.setBody_bytes_sent(formatField(body_bytes_sent));
		nginxLog.setHttp_referer(formatField(http_referer));
		nginxLog.setHttp_user_agent(formatField(http_user_agent));

		return nginxLog;
	}

	/**
	 * 此方法描述的是：解析url
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return Map<String , String > 
	 */
	public static Map<String, String> analysisTrackUrl(String trackURL) {
		Map<String, String> mapTrackUrl = new HashMap<String, String>();
		if (trackURL == null || trackURL.equals("")) {
			return mapTrackUrl;
		}
		String strTrackURL = trackURL;
		strTrackURL = strTrackURL.replace("，", ",").replace("{", "")
				.replace("｛", "").replace("}", "").replace("｝", "")
				.replace(" ", "").replace("：", ":").replace(":", "==")
				.replace("‘", "'").replace("','", "|").replace(",'", "|")
				.replace("',", "|");
		String[] paramList = strTrackURL.split("\\|");
		for (String param : paramList) {
			param = param.replace("'", "").trim();
			if (param.contains("==")) {
				String[] arrTmp = param.split("==");
				if (arrTmp.length == 2) {
					mapTrackUrl.put(param.split("==")[0], param.split("==")[1]);
				}
			}
		}
		return mapTrackUrl;
	}

	/**
	 * 此方法描述的是：解析url
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return Map<String , String > 
	 */
	public static Map<String, String> requestParamUrlToMap(String requestParamStr) {
		Map<String, String> requestParamMap = new HashMap<String, String>();

		for (String kv : requestParamStr.split("&")) {
			kv = preProcess(kv, "utf-8");

			if (kv != null && kv.indexOf("=") != -1) {
				int indexTmp = kv.indexOf("=");
				if (indexTmp != kv.length() - 1) {
					requestParamMap.put(kv.substring(0, indexTmp),kv.substring(indexTmp + 1, kv.length()));
				} else {
					requestParamMap.put(kv.substring(0, indexTmp), "");
				}

			}
		}

		return requestParamMap;
	}

	public static String getOtherParm(Map<String, String> requestParamMap){
		StringBuffer bf = new StringBuffer();
		for (Map.Entry<String, String> entry : requestParamMap.entrySet()) { 
			String key = entry.getKey();
			String val = entry.getValue();
			if(!key.equals("trackURL")){
				bf.append(key);
				bf.append("=");
				bf.append(val);
				bf.append("&");
			}
		}
		return bf.toString().substring(0, bf.toString().length()-1);
	}
	
	/**
	 * 此方法描述的是：URL  decode
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return String
	 */
	private static String preProcess(String strSources, String strCode) {
		if (!strCode.isEmpty()) {
			try {
				strSources = URLDecoder.decode(strSources, strCode);
				strSources=strSources.replace("\001", "");
				strSources=strSources.replace("\002", "");
				strSources=strSources.replace("\003", "");
				strSources=strSources.replace("\004", "");
				strSources=strSources.replace("\005", "");
				strSources=strSources.replace("\006", "");
				strSources=strSources.replace("\n", "");
				strSources=strSources.replace("\r", "");
			} catch (Exception e) {
				return "";
			}
		}
		return strSources;
	}

	/**
	 * 此方法描述的是：初始化 日志父类
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return 是否成功
	 */
	public static Boolean initBaseLog(NginxLog nginxLog, PcBaseLog baseLog) {
		
		if (nginxLog == null) {
			return false;
		}

		if (nginxLog.getRequest().indexOf("beacon.gif?") == -1
				|| nginxLog.getRequest().indexOf("HTTP/") == -1) {
			return false;
		}

		baseLog.setUserIp(nginxLog.getRemote_addr());
		baseLog.setCurUrl(preProcess(nginxLog.getRequest(), "utf-8"));
		
		String requestParam = nginxLog.getRequest().substring(nginxLog.getRequest().indexOf("beacon.gif?") + 11,nginxLog.getRequest().indexOf(" HTTP/"));
		
		requestParam=requestParam.replaceAll("&amp;", "&");
		
		baseLog.setUrlParamStr(requestParam);
		baseLog.setUserAgent(nginxLog.getHttp_user_agent());
		
		baseLog.setCookieId(baseLog.getUrlParamMap().get("_id"));
		baseLog.setType(baseLog.getUrlParamMap().get("type"));
		
		baseLog.setUserId(baseLog.getUrlParamMap().get("user_id"));
		baseLog.setGuid(baseLog.getUrlParamMap().get("guid"));
		
		//url
		String curl = preProcess(baseLog.getUrlParamMap().get("referer"), "utf-8");;
		String refurl =preProcess(baseLog.getUrlParamMap().get("referer_link"), "utf-8");
		String linkurl =preProcess(baseLog.getUrlParamMap().get("url"), "utf-8");
		
		
		Matcher m1=p1.matcher(curl);  
		Matcher m3=p3.matcher(curl);  
		Matcher m5=p5.matcher(curl);  
		if(m1.find()||m3.find()){
			curl=dealUrl(curl);
		}else if (m5.find()){
			curl=mcryptdecode(curl);
		}
		
		
		m1=p1.matcher(refurl);  
		m3=p3.matcher(refurl);  
		m5=p5.matcher(refurl);  
		if(m1.find()||m3.find()){
			refurl=dealUrl(refurl);
		}else if (m5.find()){
			refurl=mcryptdecode(refurl);
		}
		
		m1=p1.matcher(linkurl);  
		m3=p3.matcher(linkurl);  
		m5=p5.matcher(linkurl);  
		if(m1.find()||m3.find()){
			linkurl=dealUrl(linkurl);
		}else if (m5.find()){
			linkurl=mcryptdecode(linkurl);
		}
		
		curl=curl.replaceAll("&amp;", "&");
		refurl=refurl.replaceAll("&amp;", "&");
		linkurl=linkurl.replaceAll("&amp;", "&");
		
		baseLog.setCurUrl(curl);
		baseLog.setRefUrl(refurl);
		baseLog.setLinkUrl(linkurl);
		
		
		baseLog.setExtra(baseLog.getUrlParamMap().get("others"));
		
		Long timestamp = MyDateUtil.toTimeStamp(nginxLog.getTime_local());
		//timestamp=timestamp/1000;
		baseLog.setTimeStamp(timestamp.toString());
		
		//设置平台
		if(baseLog.getCurUrl()!=null){
			Map<String , String>curlParamMaps = PcLogUtil.requestParamUrlToMap(baseLog.getCurUrl().substring(baseLog.getCurUrl().indexOf("?")+1));
			baseLog.setCurlParamMap(curlParamMaps);
			String platform ;
			/*****************王振改 start**********************/
			if(baseLog.getCurUrl().startsWith("http://appview.qyer.com")||baseLog.getCurUrl().contains("source=app")){
				platform="apph5";
			}else if ((baseLog.getCurUrl().startsWith("http://m.qyer.com")||baseLog.getCurUrl().startsWith("http://dpl.qyer.com"))&&!baseLog.getCurUrl().contains("source=app")){
				platform="mobile";
			}else{
				platform = "web";
			}
			/*****************王振改 stop**********************/
			baseLog.setPlatform(platform);
		}
		return true;
	}
	
	
	 final static Pattern p6=Pattern.compile("http://www.qyer.com/tag/(.*)");
	 final static Pattern p7=Pattern.compile("http://m.qyer.com/(.*)/tag/(.*)");
	/**处理php加密
	 * 
	 * */
	public static String dealUrl(String url){
		
		try {
			String res =url;
			
			Matcher m2=p2.matcher(url);  
			Matcher m4=p4.matcher(url);  
			//Matcher m6=p6.matcher(url);  
			//Matcher m7=p7.matcher(url);  
			if(m2.find()||m4.find()){
//					||m6.find()||m7.find()){
				return res ; 
			}
			
			String idstr = "";
			Matcher m1=p1.matcher(url);  
			Matcher m3=p3.matcher(url);  
			if(m1.find()){
				idstr=m1.group(2);  
			}else if(m3.find()){
				idstr=m3.group(1);  
			}
			
			String data=idstr.replace("/","").replace("-","+").replace("_","/");
			int mod4 = data.length() % 4;
			if (mod4!=0){
				data += "====".substring(0,mod4);
			}
			String base64_str = Base64Util.decode(data.getBytes());

			String md5key = MD5.GetMD5Code("qyer10year");
			
			int ctr = 0 ;
			String  temp = "" ; 
			for(int i =0 ;i< base64_str.length() ;i++  ){
				if(ctr==md5key.length()){
					ctr=0 ; 
				}else{
					ctr=ctr;
				}
				char x =(char)((int)base64_str.charAt(i) ^ (int)md5key.charAt(ctr));
				temp += x;
				ctr++;
			}
			String text = temp; 
			String tmp ="";
			
			int i =0 ; 
			while (i<text.length()){
				char pre =text.charAt(i);
				i++;
				char x = (char)((int)text.charAt(i) ^ (int)pre); 
				tmp += x;
				i++;
			}
			res = url.replaceAll(idstr, tmp); 
			return res;
		} catch (Exception e) {
//			e.printStackTrace();
			return url ;
		}
	}
	
	static String password = Hex.toStringHex("1d46a31baeab9cf69184d1f92ba5b9f8");
	
	public static String mcryptdecode(String url){
		try {
			String res =url;
			String idstr = "";
			Matcher m5=p5.matcher(url);  
			if(m5.find()){
				idstr=m5.group(3);  
			}
			
			String data=idstr.replace("-","+").replace("_","/");
			int mod4 = data.length() % 4;
			if (mod4!=0){
				data += "====".substring(0,mod4);
			}
			String base64_str = Base64Util.decode(data.getBytes());

			byte[] decryResult = DES.decrypt(base64_str.getBytes(), password);
			String id =   new String(decryResult);
			return res.replaceAll(idstr, id);
		} catch (Exception e) {
//			e.printStackTrace();
			return url ;
		}
	}
	
	public static void main(String[] args) {
		
		String url ="http://m.qyer.com/place/poi/V2AJZFFvBzBTbVI3Cm4";
		String url1="http://m.qyer.com/plan/V20JYVFhBzBTYVI2/poi/24449371";
		System.out.println(dealUrl(url));
		System.out.println(dealUrl(url1));
		
		
		String url2 ="m.qyer.com/guide/439/page/8560/?source=app&client_id=qyer_guide&track_app_version=4.1&track_deviceid=FD87F9A3-4859-4597-9B79-07A890DF1FD9";
		System.out.println(mcryptdecode(url2));
	}
}
